package com.ruoyi.common.exception.component;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.log.RunableWrapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.concurrent.Executor;

/**
 * @author cc
 * @ClassName: com.sjsd.db.component
 * @date: 2025/4/2 10:40
 * @Description:
 */
@Component
@Slf4j
public class ExceptionAlterUtil {
    @Value("${sjsd.env:dev}")
    private String env;

    private String webHook = "https://open.feishu.cn/open-apis/bot/v2/hook/922a5bba-6e68-4992-9e8b-33ce0dc4fc4";

    private String webHookPrd = "https://open.feishu.cn/open-apis/bot/v2/hook/3ef862b0-8fd9-42ca-b8c8-3d6db12415a";

    @Resource
    private Executor exceptionTaskExecutor;


    public void sendExceptionAlert(Exception e, String scene) {
        String exceptionStackTrace;
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            exceptionStackTrace = sw.toString();
        } catch (Exception ex) {
            log.error("解析异常堆栈信息失败:", ex);
            return;
        }
        sendExceptionAlert(exceptionStackTrace, scene, null);
    }

    public void sendExceptionAlert(Exception e, String scene, String param) {
        String exceptionStackTrace;
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            exceptionStackTrace = sw.toString();
        } catch (Exception ex) {
            log.error("解析异常堆栈信息失败:", ex);
            return;
        }
        sendExceptionAlert(exceptionStackTrace, scene, param);
    }


    public void sendExceptionAlert(String message, String scene, String param) {

        exceptionTaskExecutor.execute(RunableWrapper.of(() -> {
            try {
                String title = String.format("谁叫随到-异常提醒-%s", env);
                String msg =
                        "场景: " + scene + "\n" +
                                "参数: " + param + "\n" +
                                "异常信息: " + "\n" + split(message);
                sendFeiShuMessage(title, msg);
            } catch (Exception ex) {
                log.error("异常报警提醒发送失败:", ex);
            }
        }));
    }


    /**
     * 发送到默认异常飞书群
     * @param title
     * @param msg
     */
    public void sendFeiShuMessage(String title, String msg) {
        exceptionTaskExecutor.execute(()->{
            try {
                String webHookUrl = webHook;
                if (!Objects.equals("dev", env)){
                    webHookUrl = webHookPrd;
                }
                sendFeiShuMessage(title, msg, webHookUrl);
            } catch (Exception e) {
                log.error("异常报警提醒发送失败:", e);
            }
        });
    }

    /**
     * 发送到默认异常飞书群(仅测试环境发送)
     * @param title
     * @param msg
     */
    public void sendFeiShuMessageByTest(String title, String msg) {
        if (!Objects.equals("dev", env)){
            return;
        }
        exceptionTaskExecutor.execute(()->{
            try {
                String webHookUrl = webHook;
                if (!Objects.equals("dev", env)){
                    webHookUrl = webHookPrd;
                }
                sendFeiShuMessage(title, msg, webHookUrl);
            } catch (Exception e) {
                log.error("异常报警提醒发送失败:", e);
            }
        });
    }


    /**
     * 发送到指定飞书群
     * @param title
     * @param msg
     * @param webHook
     */
    public void sendFeiShuMessage(String title, String msg, String webHook) {
        String text =
                title + "\n" +
                        "环境: " + env + "\n" +
                        "TID: " + MDC.get("tid") + "\n" +
                        "taskId: " + MDC.get("taskId") + "\n" +
                        msg;

        //请求的JSON数据，这里用map在工具类里转成json格式
        Map<String, Object> json = new HashMap<>();
        json.put("msg_type", "text");
        json.put("content", new HashMap<String, String>() {{
            put("text", text);
        }});

        String result = HttpRequest.post(webHook)
                .body(JSON.toJSONString(json))
                .execute().body();

        log.info("飞书消息发送结果:{}", result);
    }

    public String getQueryParam() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
            if (ObjectUtils.isEmpty(request)) {
                return "";
            }

            // 获取所有请求参数
            Map<String, String> params = new HashMap<>();
            Enumeration<String> paramNames = request.getParameterNames();
            while (paramNames.hasMoreElements()) {
                String paramName = paramNames.nextElement();
                String paramValue = request.getParameter(paramName);
                params.put(paramName, paramValue);
            }

            // 如果没有参数，返回空字符串
            if (params.isEmpty()) {
                return "";
            }
            StringBuilder queryString = new StringBuilder();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (queryString.length() > 0) {
                    queryString.append(",");
                }
                queryString.append(entry.getKey()).append("=").append(entry.getValue());
            }

            // 截取前 1000 个字符，防止字符串过大
            if (queryString.length() > 1000) {
                return queryString.substring(0, 1000)+"......";
            }

            return queryString.toString();
        } catch (Exception e) {
            log.error("获取请求参数失败:", e);
        }
        return "";
    }

    public String getAuthorizationHeader() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
            if (ObjectUtils.isEmpty(request)) {
                return "";
            }
            String authorizationHeader = request.getHeader("Authorization");
            if (ObjectUtils.isEmpty(authorizationHeader)) {
                return "";
            }

            return authorizationHeader;
        } catch (Exception e) {
            log.error("获取请求头失败:", e);
        }
        return "";
    }


    /**
     * 保留10行堆栈信息
     */
    private String split(String message) {
        if (StringUtils.isEmpty(message)) {
            return "";
        }
        String[] lines = message.split("\n");

        // 判断行数是否超过 10 行
        if (lines.length > 15) {
            // 如果超过 10 行，则只保留前 10 行
            lines = Arrays.copyOfRange(lines, 0, 10);
            StringBuilder sb = new StringBuilder();
            for (String line : lines) {
                sb.append(line).append("\n");
            }
            sb.append("......");
            return sb.toString();
        } else {
            return message;
        }
    }

}
